﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace TDBaseDataLibrary
{
    public class Towner : TDCharacter
    {
        //位置
        protected Vector2 TownerPos;
        protected float frange;
        protected ContentManager content;
        protected TDMap m_map;
        protected Particle m_Particle;
        protected int m_lift;
        public Towner(ContentManager content,TDWorld world,Vector2 pos,TDMap map,int lift)
        {
            m_world = world;
            TownerPos = pos;
            this.content = content;
            m_map = map;
            m_lift = lift;
        }
        public virtual void StartParticle()
        {
        }
        public virtual void EndParticle()
        {
        }
        public virtual int GetPrice()
        {
            return 0;
        }
        public virtual bool CanReach(Vector2 vstar,Vector2 vend)
        {
            return true;
        }
        public override bool Update(GameTime time)
        {
            return true;
        }

        public override void Draw(GraphicsDeviceManager graphics, GameTime gameTime, SpriteBatch spriteBatch, int OffsetX, int OffsetY)
        {
        }
    }

    enum townerstate
    {
        townerstate_reload  = 0,
        townerstate_fire    = 1,
        townerstate_idel    = 2,
    }
    public class FireTowner : Towner
    {
        float froate;
        Texture2D level_townerB;
        float time;
        GameAmm ammSprite;
        int nImgIndex;
        ammFire fire;
        TDCharacter LockEnemy;
        FireParticle ammParticle;
        public static int price = 0;



        public FireTowner(ContentManager content, TDWorld world, Vector2 pos, TDMap map, int lift)
            : base(content, world,pos, map,lift)
        {
            state = spritestate.townerstate_idel;
            frange = 200;
            nImgIndex = 0;
            level_townerB = content.Load<Texture2D>("TownerFire");
            Texture2D tex = content.Load<Texture2D>("fire");
            ammParticle = new FireParticle(content, pos);
            Vector2 centerArrow = new Vector2(8, 0);
            if (ammSprite == null)
                ammSprite = new GameAmm(tex, 0, true, 16, 128, 10, centerArrow, 0);
        }
        public override bool CanReach(Vector2 vstar,Vector2 vend)
        {
            Vector2 v = vend - vstar;
            if (Math.Abs(v.X) > Math.Abs(v.Y))
            {
                float fstep = v.Y / Math.Abs(v.X);
                int nxstep = v.X > 0 ? 1 : -1;
                float y = vstar.Y;
                int nsx = (int)vstar.X;
                int nex = (int)vend.X;
                for (int i = nsx; i != nex; i += nxstep)
                {
                    int nycell = ((int)y) / m_map.m_cellPixel;
                    int nxcell = i / m_map.m_cellPixel;
                    if (m_map.m_Cell[nycell * m_map.m_nCellWidth + nxcell] > 0)
                        return false;
                    y += fstep;
                }
            }
            else
            {
                float fstep = v.X / Math.Abs(v.Y);
                int nystep = v.Y > 0 ? 1 : -1;
                float x = vstar.X;

                int nsy = (int)vstar.Y;
                int ney = (int)vend.Y;

                for (int i = nsy; i != ney; i += nystep)
                {
                    int nxcell = ((int)x) / m_map.m_cellPixel;
                    int nycell = i / m_map.m_cellPixel;
                    if (m_map.m_Cell[nycell * m_map.m_nCellWidth + nxcell] > 0)
                        return false;
                    x += fstep;
                }
            }
            return true;
        }
        public override bool Update(GameTime time)
        {
            ammParticle.Update(time);
            if (m_world.m_enemyList != null && m_world.m_enemyList.Count > 0)
            {
                Enemy e = null;
                for (int i = 0; i < m_world.m_enemyList.Count; i++)
                {
                    if (Vector2.DistanceSquared(m_world.m_enemyList[i].m_pos, TownerPos) < frange * frange)
                    {
                        if (CanReach(m_world.m_enemyList[i].m_pos, TownerPos) == false)
                            continue;
                        e = (Enemy)m_world.m_enemyList[i];
                        if (LockEnemy != e)
                        {
                            LockEnemy = e;
                            if (state == spritestate.townerstate_idel)
                            {
                                state = spritestate.townerstate_fire;
                                ammParticle.Start(time);
                            }
                        }
                        break;
                    }
                }

                if (e != null)
                {
                    if (state == spritestate.townerstate_reload)
                    {
                        this.time -= (float)time.ElapsedGameTime.TotalMilliseconds;
                        if (this.time < 0)
                        {
                            state = spritestate.townerstate_fire;
                            ammParticle.Start(time);
                            this.time = 0;
                        }
                    }

                    Vector2 pt = e.Pos;
                    Vector2 v = new Vector2(pt.X - TownerPos.X, pt.Y - TownerPos.Y);
                    Vector2 vOrig = new Vector2(0, 1);
                    froate = TownerMath.calcAngle(v, vOrig);
                    ammParticle.Direct = froate;
                    if (state == spritestate.townerstate_fire)
                    {
                        if(fire == null)
                            fire = new ammFire(ammSprite, froate, TownerPos);
                        fire.Update(time, e, froate);
                        if(fire.Dead)
                        {
                            fire = null;
                            state = spritestate.townerstate_reload;
                            ammParticle.Stop(time);
                            this.time = 2000;
                        }
                    }
                }
            }
            return true;
        }
        public override void Draw(GraphicsDeviceManager graphics, GameTime gameTime, SpriteBatch spriteBatch, int OffsetX, int OffsetY)
        {
            Rectangle rttownerA = new Rectangle((int)TownerPos.X + OffsetX, (int)TownerPos.Y + OffsetY, 32, 32);
            Rectangle rttownerASrc = new Rectangle(0, 0, 32, 32);
            Vector2 vrotate = new Vector2(16, 16);
            spriteBatch.Draw(level_townerB, rttownerA, rttownerASrc, Color.White, froate, vrotate, SpriteEffects.None, 0);
            //if(fire != null)
            //    fire.Draw(graphics, gameTime, spriteBatch,OffsetX,OffsetY);
            ammParticle.Draw(graphics, gameTime, spriteBatch, OffsetX, OffsetY);
        }
    }

    public class WaterTowner : Towner
    {
        float froate;
        Texture2D level_townerB;
        float time;
        GameAmm ammSprite;
        int nImgIndex;
        ammFire water;
        TDCharacter LockEnemy;
        WaterParticle ammParticle;
        public static int price = 500;



        public WaterTowner(ContentManager content, TDWorld world, Vector2 pos, TDMap map, int lift)
            : base(content, world,pos,map,lift)
        {
            state = spritestate.townerstate_idel;
            frange = 200;
            nImgIndex = 0;
            level_townerB = content.Load<Texture2D>("TownerFire");
            Texture2D tex = content.Load<Texture2D>("fire");
            price = 500;
            ammParticle = new WaterParticle(content, pos);
            Vector2 centerArrow = new Vector2(8, 0);
            if (ammSprite == null)
                ammSprite = new GameAmm(tex, 0, true, 16, 128, 10, centerArrow, 0);
        }
        public override int GetPrice()
        {
            return 500;
        }
        public override bool Update(GameTime time)
        {
            ammParticle.Update(time);
            if (m_world.m_enemyList != null && m_world.m_enemyList.Count > 0)
            {
                Enemy e = null;
                for (int i = 0; i < m_world.m_enemyList.Count; i++)
                {
                    if (Vector2.DistanceSquared(m_world.m_enemyList[i].m_pos, TownerPos) < frange * frange)
                    {
                        if (CanReach(m_world.m_enemyList[i].m_pos, TownerPos) == false)
                            continue;
                        e = (Enemy)m_world.m_enemyList[i];
                        if (LockEnemy != e)
                        {
                            LockEnemy = e;
                            if (state == spritestate.townerstate_idel)
                            {
                                state = spritestate.townerstate_fire;
                                ammParticle.Start(time);
                            }

                        }
                        break;
                    }
                }


                if (e != null)
                {
                    if (state == spritestate.townerstate_reload)
                    {
                        this.time -= (float)time.ElapsedGameTime.TotalMilliseconds;
                        if (this.time < 0)
                        {
                            state = spritestate.townerstate_fire;
                            ammParticle.Start(time);
                            this.time = 0;
                        }
                    }

                    Vector2 pt = e.Pos;
                    Vector2 v = new Vector2(pt.X - TownerPos.X, pt.Y - TownerPos.Y);
                    Vector2 vOrig = new Vector2(0, 1);
                    froate = TownerMath.calcAngle(v, vOrig);
                    ammParticle.Direct = froate;
                    if (state == spritestate.townerstate_fire)
                    {
                        if (water == null)
                            water = new ammFire(ammSprite, froate, TownerPos);
                        water.Update(time, e, froate);
                        if (water.Dead)
                        {
                            water = null;
                            state = spritestate.townerstate_reload;
                            ammParticle.Stop(time);
                            this.time = 2000;
                        }
                    }
                }
            }
            return true;
        }
        public override void Draw(GraphicsDeviceManager graphics, GameTime gameTime, SpriteBatch spriteBatch, int OffsetX, int OffsetY)
        {
            Rectangle rttownerA = new Rectangle((int)TownerPos.X + OffsetX, (int)TownerPos.Y + OffsetY, 32, 32);
            Rectangle rttownerASrc = new Rectangle(0, 0, 32, 32);
            Vector2 vrotate = new Vector2(16, 16);
            spriteBatch.Draw(level_townerB, rttownerA, rttownerASrc, Color.White, froate, vrotate, SpriteEffects.None, 0);
            //if(fire != null)
            //    fire.Draw(graphics, gameTime, spriteBatch,OffsetX,OffsetY);
            ammParticle.Draw(graphics, gameTime, spriteBatch, OffsetX, OffsetY);
        }
    }
    public class ArrowTowner : Towner
    {
        float froate;
        Texture2D level_townerA;
        Texture2D fire_Texture;
        float time;
        List<Arrow> arrowList;
        static GameAmm ammSprite;
        List<fire> fireList;
        public static int price = 10;

        public ArrowTowner(ContentManager content, TDWorld world, Vector2 pos, TDMap map, int lift) :
            base(content, world,pos, map, lift)
        {
            frange = 200;
            price = 10;
            level_townerA = content.Load<Texture2D>("TownerArrow");
            Texture2D tex = content.Load<Texture2D>("Arrow");
            fire_Texture = content.Load<Texture2D>("fireArrow");
            Vector2 centerArrow = new Vector2(4, 0);
            
            if(ammSprite == null)
                ammSprite = new GameAmm(tex, 0, true, 8, 32, 1, centerArrow, 1000);
            arrowList = new List<Arrow>();
            fireList = new List<fire>();
        }
        public override bool Update(GameTime time)
        {
            if (m_world.m_enemyList != null && m_world.m_enemyList.Count > 0)
            {
                Enemy e = null;
                for (int i = 0; i < m_world.m_enemyList.Count; i++)
                {
                    if (Vector2.DistanceSquared(m_world.m_enemyList[i].m_pos, TownerPos) < frange * frange)
                    {
                        if (CanReach(m_world.m_enemyList[i].m_pos, TownerPos) == false)
                            continue;
                        e = (Enemy)m_world.m_enemyList[i];
                        break;
                    }
                }

                if (e != null)
                {
                    Vector2 pt = e.Pos;
                    Vector2 v = new Vector2(pt.X - TownerPos.X, pt.Y - TownerPos.Y);
                    Vector2 vOrig = new Vector2(0, 1);
                    froate = TownerMath.calcAngle(v, vOrig);
                    this.time += (float)time.ElapsedGameTime.TotalMilliseconds;
                    if (this.time >= 500)
                    {
                        this.time -= 500;
                        Vector2 vPos = new Vector2(TownerPos.X, TownerPos.Y);
                        Arrow a = new Arrow(ammSprite, froate, vPos);
                        Color c = new Color(0, 255, 0, 255);
                        fire f = new fire(content,e, vPos, froate, 800, c,fire_Texture);
                        fireList.Add(f);
                        arrowList.Add(a);
                    }
                }
                for (int i = 0; i < arrowList.Count; i++)
                {
                    arrowList[i].Update(time, e);
                    if (arrowList[i].dead)
                    {
                        arrowList.RemoveAt(i);
                        i--;
                    }
                    
                }

                for (int i = 0; i < fireList.Count; i++)
                {
                    fireList[i].Update(time);
                    if (fireList[i].dead)
                    {
                        fireList.RemoveAt(i);
                        i--;
                    }
                }

            }

            return true;   
        }

        public override void Draw(GraphicsDeviceManager graphics, GameTime gameTime, SpriteBatch spriteBatch, int OffsetX, int OffsetY)
        {
            Rectangle rttownerA = new Rectangle((int)TownerPos.X + OffsetX, (int)TownerPos.Y + OffsetY, 32, 32);
            Rectangle rttownerASrc = new Rectangle(0, 0, 32, 32);
            Vector2 vrotate = new Vector2(16, 16);

            spriteBatch.Draw(level_townerA, rttownerA, rttownerASrc, Color.White, froate, vrotate, SpriteEffects.None, 0);
            //for (int i = 0; i < arrowList.Count; i++)
            //{
            //    arrowList[i].Draw(graphics, gameTime, spriteBatch,OffsetX,OffsetY);
            //}
            for (int i = 0; i < fireList.Count; i++)
            {
                fireList[i].Draw(graphics, gameTime, spriteBatch, OffsetX, OffsetY);
            }
        }
    }
}
